package com.gk.panda.apis.log;

import com.gk.panda.apis.service.LogService;
import com.gk.panda.commons.exception.ErrorCode;
import com.gk.panda.commons.result.Result;
import com.gk.panda.commons.rsa.RsaService;
import com.gk.panda.commons.util.UserUtil;
import com.gk.panda.pojo.OperationLog;
import io.swagger.annotations.ApiOperation;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Map;

@Aspect
@Component
public class OperationLogAop {

    @Autowired
    private LogService operationLogService;

    @Autowired
    private RsaService rsaService;

    @Pointcut("execution(* com.gk.panda.apis.controller..*(..))")
    public void pointcut() {

    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint pjp) {
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        Object proceed = null;
        if (method.getAnnotation(Log.class) != null) {
            String className = method.getDeclaringClass().getName();
            String methodName = method.getName();
            Object[] args = pjp.getArgs();
            String argInfo = Arrays.toString(args);
            String path = String.format("%s::%s(%s)", className, methodName, argInfo);
            String operation = null;
            ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);
            if (apiOperation != null){
                operation = apiOperation.value();
            }
            String username = UserUtil.getCurrentUser();
            Throwable throwable = null;
            try {
                proceed = pjp.proceed();
//                Result r = (Result) proceed;
//                if (r.getCode() == 200) {
                    OperationLog operationLog = new OperationLog().setOperation(operation).setOperator(username);
                    operationLogService.save(operationLog);
//                }
            } catch (Throwable t) {
                t.printStackTrace();
                return Result.error(ErrorCode.INTERNAL_SERVER_ERROR);
            }
            return proceed;
        }
        try {
            proceed = pjp.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            return Result.error(ErrorCode.INTERNAL_SERVER_ERROR);
        }

        return proceed;
    }
}